package org.xml.create.SAX;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.xml.Book;
import org.xml.parser.SAX.SAXParserHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

/**
 * 用SAX方式生成XML文件
 */
public class SAXTest {

	public static void main(String[] args) throws ParserConfigurationException,
			SAXException, IOException, TransformerConfigurationException {
		newXMLBySAX();// 通过ArrayList中的存储的Book对象创建XML
		newXMLBySAX2();// 通过纯手动编码的方式生成XML
	}

	private static void newXMLBySAX() throws ParserConfigurationException,
			SAXException, IOException, TransformerConfigurationException {
		ArrayList<Book> bookList = saxParser();
		// 1.创建一个SAXTransformerFactory对象
		SAXTransformerFactory stff = (SAXTransformerFactory) SAXTransformerFactory
				.newInstance();
		// 2.通过SAXTransformerFactory创建一个TransformerHandler对象
		TransformerHandler handler = stff.newTransformerHandler();

		// 3.通过TransformerHandler对象，创建一个Transformer对象
		Transformer transformer = handler.getTransformer();
		transformer.setOutputProperty(OutputKeys.ENCODING, "GBK");
		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
		// 4.创建一个Result对象
		Result result = new StreamResult(new FileOutputStream("books_sax.xml"));
		// 5.将Result对象与StreamResult对象进行关联
		handler.setResult(result);

		// 6.利用Handler对象进行XML文件内容的编写
		handler.startDocument();// 打开Document
		AttributesImpl attr = new AttributesImpl();// attr可以被重复利用
		handler.startElement(null, null, "bookstore", attr);

		for (Book book : bookList) {
			attr.clear();
			attr.addAttribute("", "", "id", "", book.getId());
			handler.startElement(null, null, "book", attr);

			attr.clear();
			if (book.getName() != null && !book.getName().trim().equals("")) {// 避免出现空指向异常和生成无用节点
				handler.startElement("", "", "name", attr);
				handler.characters(book.getName().toCharArray(), 0, book
						.getName().length());
				handler.endElement("", "", "name");
			}
			attr.clear();
			if (book.getAuthor() != null && !book.getAuthor().trim().equals("")) {
				handler.startElement("", "", "author", attr);
				handler.characters(book.getAuthor().toCharArray(), 0, book
						.getAuthor().length());
				handler.endElement("", "", "author");
			}
			if (book.getYear() != null && !book.getYear().trim().equals("")) {
				handler.startElement("", "", "year", attr);
				handler.characters(book.getYear().toCharArray(), 0, book
						.getYear().length());
				handler.endElement("", "", "year");
			}
			if (book.getPrice() != null && !book.getPrice().trim().equals("")) {
				handler.startElement("", "", "price", attr);
				handler.characters(book.getPrice().toCharArray(), 0, book
						.getPrice().length());
				handler.endElement("", "", "price");
			}
			if (book.getLanguage() != null
					&& !book.getPrice().trim().equals("")) {
				handler.startElement("", "", "language", attr);
				handler.characters(book.getLanguage().toCharArray(), 0, book
						.getLanguage().length());
				handler.endElement("", "", "language");
			}
			handler.endElement("", "", "book");
		}
		handler.endElement("", "", "bookstore");
		handler.endDocument();// 关闭Document

	}

	private static void newXMLBySAX2()
			throws TransformerConfigurationException,
			TransformerFactoryConfigurationError, SAXException {
		SAXTransformerFactory stff = (SAXTransformerFactory) SAXTransformerFactory
				.newInstance();
		TransformerHandler handler = stff.newTransformerHandler();
		Transformer transformer = handler.getTransformer();
		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
		transformer.setOutputProperty(OutputKeys.ENCODING, "gb2312");
		handler.setResult(new StreamResult(new File("books_sax2.xml")));
		handler.startDocument();
		AttributesImpl attr = new AttributesImpl();
		handler.startElement("", "", "bookstore", attr);
		attr.addAttribute("", "", "id", "", "1");
		handler.startElement("", "", "book", attr);
		attr.clear();// 清除属性列表
		handler.startElement("", "", "name", attr);
		handler.characters("冰与火之歌".toCharArray(), 0, "冰与火之歌".length());
		handler.endElement("", "", "name");
		handler.startElement("", "", "author", attr);
		handler.characters("乔治马丁".toCharArray(), 0, "乔治马丁".length());
		handler.endElement("", "", "author");
		handler.endElement("", "", "book");
		attr.addAttribute("", "", "id", "", "2");
		handler.startElement("", "", "book", attr);
		attr.clear();
		handler.startElement("", "", "language", attr);
		handler.characters("英语".toCharArray(), 0, "英语".length());
		handler.endElement("", "", "language");
		handler.endElement("", "", "book");
		handler.endElement("", "", "bookstore");
		handler.endDocument();
	}

	public static ArrayList<Book> saxParser()
			throws ParserConfigurationException, SAXException, IOException {
		// 1.获取一个SAXParserFactory的实例
		SAXParserFactory factory = SAXParserFactory.newInstance();
		// 2.通过factory获取SAXParser实例
		SAXParser parser = factory.newSAXParser();
		// 3.创建一个SAXParserHandler对象
		SAXParserHandler handler = new SAXParserHandler();
		// 4.通过SAXParser对象的parse（String uri,DefaultHandler dh）方法解析xml文件
		parser.parse("books1.xml", handler);

		/* 将XML文件中的数据保存在Book对象中并将对象添加到ArrayList中 */
		ArrayList<Book> books = handler.getBookList();
		return books;
	}

}
